package resml

import "net/url"

// 根据 URL 客户端，用于根据 URL 自动判别资源类型，并生成资源接口。

// 可定位的 URL 客户端
type UrlClient struct {
	local  Storage // 本地存储，如果为 nil，则不支持本地缓存。
	etager ETager  // 资源 ETag 的生成方法
}

// 创建 URL 客户端，如果 local 为 nil，则不支持本地缓存。
func NewUrlClient(local Storage) *UrlClient {
	return &UrlClient{
		local: local,
	}
}

// 设置 ETag 的创建方法。
func (uc *UrlClient) WithETagCreation(etager ETager) *UrlClient {
	uc.etager = etager
	return uc
}

// 获取资源，如果协议不支持，返回 nil。远程资源不支持写入。
// 资源可能实现了 GetProgress 或 Progress 接口，可用于获取进度。
func (uc *UrlClient) Get(uri *url.URL) Resource {
	return uc.GetWithMeta(uri, nil)
}

// 获取资源并设置元数据，如果协议不支持，返回 nil。远程资源不支持写入。
// 资源可能实现了 GetProgress 或 Progress 接口，可用于获取进度。
func (uc *UrlClient) GetWithMeta(uri *url.URL, meta Meta) Resource {
	return uc.get(uri, meta, false)
}

// 获取资源并设置元数据，如果协议不支持，返回 nil。远程资源支持写入。
// 资源可能实现了 GetProgress 或 Progress 接口，可用于获取进度。
func (uc *UrlClient) GetWritableWithMeta(uri *url.URL, meta Meta) Resource {
	return uc.get(uri, meta, true)
}

func (uc *UrlClient) get(uri *url.URL, meta Meta, writable bool) Resource {
	if uri == nil {
		return nil
	}
	if uc.local == nil {
		return uc.getByUriWithMeta(uri, meta)
	}
	return NewCachedResource(uc.local, uc.getByUriWithMeta(uri, meta), writable)
}

// 根据 URL 创建资源实例
func (uc *UrlClient) getByUriWithMeta(uri *url.URL, meta Meta) Resource {
	switch uri.Scheme {
	case "http", "https":
		return NewHttpResource(uri, meta)
	case "file":
		return NewFileResource(uri, uc.etager)
	case "smb", "smb2", "samba":
		return NewSambaResource(uri, uc.etager)
	}
	return nil
}
